﻿#pragma warning disable 1591

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Web.Routing;

namespace TotalFreedomBST
{
    /// <summary>
    /// Extension class for HtmlHelper class of System.Mvc.Web
    /// </summary>
    public static class BstHelperExtensions
    {
        #region Accordion

        /// <summary>
        /// Create an instance of Accordion class
        /// </summary>
        /// <param name="htmlHelper">Html helper</param>
        /// <param name="id">Html "id" tag if you want to use you own id</param>
        /// <param name="htmlAttributes">An object that holds html attributes for accordion container</param>
        /// <returns>Accordion class</returns>
        public static Accordion CreateBootstrapAccordion(this HtmlHelper htmlHelper, string id = null, object htmlAttributes = null)
        {
            RouteValueDictionary attrs = null;
            if (htmlAttributes != null)
                attrs = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);

            return new Accordion(id, attrs);
        }

        public static AccordionSection BootstrapAccordion(this HtmlHelper htmlHelper, string id = null, object htmlAttributes = null)
        {
            AccordionSection section = new AccordionSection(htmlHelper, null, id, htmlAttributes);

            htmlHelper.ViewContext.Writer.Write(section.StartHtml());

            return section;
        }

        public static AccordionSection BootstrapAccordion(this HtmlHelper htmlHelper, Accordion accordion, string id = null, object htmlAttributes = null)
        {
            AccordionSection section = new AccordionSection(htmlHelper, accordion, id, htmlAttributes);

            htmlHelper.ViewContext.Writer.Write(section.StartHtml());

            return section;
        }

        public static AccordionGroupSection BootstrapAccordionGroup(this HtmlHelper htmlHelper, Accordion accordion, string header, string id = null, object htmlAttributes = null)
        {
            return BootstrapAccordionGroup(htmlHelper, accordion, new MvcHtmlString(HttpUtility.HtmlEncode(header)), id, htmlAttributes);
        }

        public static AccordionGroupSection BootstrapAccordionGroup(this HtmlHelper htmlHelper, Accordion accordion, MvcHtmlString header, string id = null, object htmlAttributes = null)
        {
            RouteValueDictionary attrs = null;
            if (htmlAttributes != null)
                attrs = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes); 

            AccordionGroupSection accordionGroupSection = new AccordionGroupSection(accordion, htmlHelper.ViewContext, null, AccordionGroupOptions.None, id, attrs);

            htmlHelper.ViewContext.Writer.Write(accordionGroupSection.StartHtml(header));

            return accordionGroupSection;
        }



        #endregion

        #region Tab

        public static Tab CreateBootstrapTab(this HtmlHelper htmlHelper, TabOptions options = TabOptions.None, string id = null, object htmlAttributes = null)
        {
            RouteValueDictionary attrs = null;
            if (htmlAttributes != null)
                attrs = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);

            return new Tab(htmlHelper, options, id, attrs);
        }

        public static TabSection BootstrapTab(this HtmlHelper htmlHelper, Tab tab, TabOptions options = TabOptions.None, string id = null, object htmlAttributes = null)
        {
            RouteValueDictionary attrs = null;
            if (htmlAttributes != null)
                attrs = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);

            TabSection section = new TabSection(htmlHelper, tab, id, options, attrs);

            htmlHelper.ViewContext.Writer.Write(section.StartHtml());

            return section;
        }
        

        #endregion   
    
        #region TabNav

        public static TabNav CreateBootstrapTabNav(this HtmlHelper htmlHelper, TabNavOptions options = TabNavOptions.None, string id = null, object htmlAttributes = null)
        {
            RouteValueDictionary attrs = null;
            if (htmlAttributes != null)
                attrs = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);

            return new TabNav(htmlHelper, options, id, attrs);
        }

        public static TabNavSection BootstrapTabNav(this HtmlHelper htmlHelper, TabNav tabNav, TabNavOptions options = TabNavOptions.None, string id = null, object htmlAttributes = null)
        {
            RouteValueDictionary attrs = null;
            if (htmlAttributes != null)
                attrs = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);

            TabNavSection section = new TabNavSection(htmlHelper, tabNav, id, options, attrs);

            htmlHelper.ViewContext.Writer.Write(section.StartHtml());

            return section;
        }

        #endregion    

        #region Carousel

        public static Carousel CreateBootstrapCarousel(this HtmlHelper htmlHelper, string id = null)
        {
            return new Carousel(htmlHelper, id);
        }

        public static CarouselSection BootstrapCarousel(this HtmlHelper htmlHelper, Carousel carousel, string id = null)
        {
            CarouselSection section = new CarouselSection(htmlHelper, carousel: carousel, id: id);

            htmlHelper.ViewContext.Writer.Write(section.StartHtml());

            return section;
        }


        #endregion   
    
        #region HTML helpers

        public static string AttributeOrDefault(RouteValueDictionary attrs, string attributeName, string defaultValue)
        {
            string result = defaultValue;
            if (attrs != null && attrs.ContainsKey(attributeName))
            {
                object v = attrs[attributeName];
                if (v != null)
                    result = v.ToString();
            }

            if (result == null)
                return "";
            else
                return " " + attributeName + "=\"" + HttpUtility.HtmlAttributeEncode(result) + "\"";
        }

        public static string ValuePlusAttribute(string attributeName, string value, RouteValueDictionary attrs)
        {
            string result = "";
            if (attrs != null && attrs.ContainsKey(attributeName))
            {
                object v = attrs[attributeName];
                if (v != null)
                    result = " " + v.ToString();
            }

            return " " + attributeName + "=\"" + HttpUtility.HtmlAttributeEncode(value) + HttpUtility.HtmlAttributeEncode(result) + "\"";
        }

        public static string HtmlFromAttributes(RouteValueDictionary attrs, string[] exceptAttrs = null)
        {
            string s = "";

            if (attrs != null)
            {
                IEnumerable<string> keys = exceptAttrs == null ? attrs.Keys : attrs.Keys.Where(w => exceptAttrs == null || !exceptAttrs.Contains(w));
                foreach (string key in keys)
                {
                    object value = attrs[key];
                    if (value != null)
                        s += " " + key + "=\"" + HttpUtility.HtmlAttributeEncode(value.ToString()) + "\"";
                }
            }

            return s;
        }

        public static IHtmlContainer Container(this HtmlHelper htmlHelper, string content = null, object htmlAttributes = null)
        {
            RouteValueDictionary attrs = null;
            if (htmlAttributes != null)
                attrs = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes); 

            HtmlContainer<SimpleContainer> container = new HtmlContainer<SimpleContainer>(htmlHelper, content, attrs);

            return container;
        }

        public static IHtmlContainer Container<T>(this HtmlHelper htmlHelper, string content = null, object htmlAttributes = null) where T : IHtmlContainer
        {
            RouteValueDictionary attrs = null;
            if (htmlAttributes != null)
                attrs = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);

            HtmlContainer<T> container = new HtmlContainer<T>(htmlHelper, content, attrs);

            return container;
        }

        public static IHtmlElement Element<T>(this HtmlHelper htmlHelper, string content, object htmlAttributes = null) where T : IHtmlElement
        {
            RouteValueDictionary attrs = null;
            if(htmlAttributes != null)
                attrs = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);

            Type t = typeof(T);
            if( typeof(IHtmlSrcElement).IsAssignableFrom(t))
            {
                var url = new UrlHelper(htmlHelper.ViewContext.RequestContext);
                content = url.Content(content);
            }

            HtmlElement<T> element = new HtmlElement<T>(content, attrs);

            return element;
        }

        #endregion

        #region VisiToggler

        public static VisiToggler CreateVisiToggler(this HtmlHelper htmlHelper, string switchContent, VisiOptions options = VisiOptions.Toggle, string id = null, object htmlAttributes = null)
        {
            return CreateVisiToggler(htmlHelper, new MvcHtmlString(switchContent), options, id, htmlAttributes);
        }

        public static VisiToggler CreateVisiToggler(this HtmlHelper htmlHelper, IHtmlString switchContent, VisiOptions options = VisiOptions.Toggle, string id = null, object htmlAttributes = null)
        {
            RouteValueDictionary attrs = null;
            if (htmlAttributes != null)
                attrs = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);

            VisiToggler result = new VisiToggler(switchContent, id, options, attrs);

            return result;
        }

        public static VisiTogglerSection VisiToggler(this HtmlHelper htmlHelper, string content, VisiOptions options = VisiOptions.Toggle, string id = null, object htmlAttributes = null)
        {            
            return VisiToggler(htmlHelper, new MvcHtmlString(HttpUtility.HtmlEncode(content)), options, id, htmlAttributes);
        }

        public static VisiTogglerSection VisiToggler(this HtmlHelper htmlHelper, MvcHtmlString content, VisiOptions options = VisiOptions.Toggle, string id = null, object htmlAttributes = null)
        {
            VisiToggler toggler = CreateVisiToggler(htmlHelper, content, options, id, htmlAttributes);

            return VisiToggler(htmlHelper, toggler, options, null);
        }

        public static VisiTogglerSection VisiToggler(this HtmlHelper htmlHelper, VisiToggler visiTogger, VisiOptions options = VisiOptions.Toggle, object htmlAttributes = null)
        {
            RouteValueDictionary attrs = null;
            if (htmlAttributes != null)
                attrs = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);

            VisiTogglerSection section = new VisiTogglerSection(htmlHelper, visiTogger, attrs);
            htmlHelper.ViewContext.Writer.Write(section.StartHtml());

            return section;
        }

        public static MvcHtmlString VisiTogglerFromPartial(this HtmlHelper htmlHelper, string partialName, string switchContent, object model = null, ViewDataDictionary viewData = null, VisiOptions options = VisiOptions.Toggle, string id = null, object htmlAttributes = null)
        {
            return VisiTogglerFromPartial(htmlHelper, partialName, new MvcHtmlString(HttpUtility.HtmlEncode(switchContent)), model, viewData, options, id, htmlAttributes);
        }

        public static MvcHtmlString VisiTogglerFromPartial(this HtmlHelper htmlHelper, string partialName, MvcHtmlString switchContent, object model = null, ViewDataDictionary viewData = null, VisiOptions options = VisiOptions.Toggle, string id = null, object htmlAttributes = null)
        {
            VisiToggler visiToggler = CreateVisiToggler(htmlHelper, switchContent, options, id, null);

            return VisiTogglerFromPartial(htmlHelper, partialName, visiToggler, model, viewData, options, id, htmlAttributes);
        }

        public static MvcHtmlString VisiTogglerFromPartial(this HtmlHelper htmlHelper, string partialName, VisiToggler visiToggler, object model = null, ViewDataDictionary viewData = null, VisiOptions options = VisiOptions.Toggle, string id = null, object htmlAttributes = null)
        {
            RouteValueDictionary attrs = null;
            if (htmlAttributes != null)
                attrs = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);

            string s = "";
            if (!visiToggler.HadOutput)
                s += visiToggler.ToHtmlString();

            s += "<div id=\"" + HttpUtility.HtmlAttributeEncode(visiToggler.SectionId) + "\"";

            if ((visiToggler.Options & VisiOptions.HiddenByDefault) == VisiOptions.HiddenByDefault || (options & VisiOptions.HiddenByDefault) == VisiOptions.HiddenByDefault)
                s += " style=\"display: none;\"";

            if (attrs != null)
                s += BstHelperExtensions.HtmlFromAttributes(attrs);

            s += ">";
            s += htmlHelper.Partial(partialName, model, viewData).ToHtmlString();
            s += "</div>";

            return new MvcHtmlString(s);
        }

        #endregion
    }
}
